#include <Windows.h>
#include "allocator.h"

CMsgAllocater* theAllocater=0;
CMsgAllocater::CMsgAllocater(IMemoryStrategy* strategy)
:CMemory(strategy)
{
	theAllocater = this;
	ptr_block = alloc_block();
	alloc_pos  = 0;
}

CMsgAllocater::~CMsgAllocater()
{
	free_block(ptr_block);
	ptr_block = 0;
	theAllocater = 0;
}

void CMsgAllocater::adjust(uint32 require_size)
{
	if((g_options.max_message_size-alloc_pos)<require_size)
	{
		free_block(ptr_block);
		ptr_block = alloc_block();
		alloc_pos = 0;
	}
}

struct msg*	CMsgAllocater::alloc_sized_msg(uint32 size)
{
	msg* ret = 0;

	data_lock.Lock();
		adjust(size);
		ret = CMemory::alloc_msg();
		(ptr_block->duplicate(),ret->data = ptr_block);
		ret->readpos = alloc_pos;
		ret->writepos = alloc_pos;
		ret->totalsize = size;
		alloc_pos += size;
	data_lock.UnLock();

	return ret;
}

list_t<struct msg*> 
CMsgAllocater::copy_msg(struct msg* ptr_msg,int count)
{
	list_t<struct msg*> ret;

	int len = ptr_msg->len();
	for(int i = 0; i<count;++i)
	{
		struct msg* new_msg = alloc_sized_msg(len);
		memcpy((void*)new_msg->base(),(void*)ptr_msg->base(),len);
		new_msg->writepos = new_msg->readpos + len;
		ret.add_tail(new_msg);
	}

	return ret;
}